package com.gobang.controller;

import com.gobang.domain.dto.LoginRequestDTO;
import com.gobang.domain.vo.LoginResponseVO;
import com.gobang.domain.vo.Result;
import com.gobang.service.AuthService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;

/**
 * 认证授权控制器
 * 提供用户登录、登出、Token验证等认证相关API
 * 
 * @author System
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
@Validated
public class AuthController {

    private final AuthService authService;

    /**
     * 用户登录
     * 验证用户名密码，返回JWT Token和用户信息
     *
     * @param loginRequest 登录请求数据
     * @return 登录响应结果
     */
    @PostMapping("/login")
    public Result<LoginResponseVO> login(@Valid @RequestBody LoginRequestDTO loginRequest) {
        log.info("用户登录请求，用户名：{}", loginRequest.getUsername());
        
        try {
            LoginResponseVO response = authService.login(loginRequest);
            log.info("用户登录成功，用户名：{}", loginRequest.getUsername());
            return Result.success(response, "登录成功");
        } catch (Exception e) {
            log.error("用户登录失败，用户名：{}，错误：{}", loginRequest.getUsername(), e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 用户登出
     * 销毁用户会话，清理缓存信息
     *
     * @return 登出结果
     */
    @PostMapping("/logout")
    public Result<Void> logout() {
        // 从Security上下文获取当前用户ID
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
        if (authentication != null && authentication.getPrincipal() instanceof Long userId) {
            log.info("用户登出请求，用户ID：{}", userId);
            
            try {
                boolean success = authService.logout(userId);
                if (success) {
                    log.info("用户登出成功，用户ID：{}", userId);
                    return Result.success("登出成功");
                } else {
                    log.warn("用户登出失败，用户ID：{}", userId);
                    return Result.error("LOGOUT_FAILED", "登出失败");
                }
            } catch (Exception e) {
                log.error("用户登出异常，用户ID：{}，错误：{}", userId, e.getMessage(), e);
                return Result.error("LOGOUT_ERROR", "登出异常");
            }
        } else {
            log.warn("用户登出失败，未找到认证信息");
            return Result.error("USER_NOT_LOGIN", "用户未登录");
        }
    }

    /**
     * 验证Token有效性
     * 检查当前Token是否有效
     *
     * @param token JWT Token
     * @return 验证结果
     */
    @GetMapping("/validate")
    public Result<Boolean> validateToken(@RequestParam("token") String token) {
        log.debug("Token验证请求");
        
        try {
            boolean isValid = authService.validateToken(token);
            log.debug("Token验证结果：{}", isValid);
            return Result.success(isValid, isValid ? "Token有效" : "Token无效");
        } catch (Exception e) {
            log.error("Token验证异常，错误：{}", e.getMessage(), e);
            return Result.success(false, "Token验证异常");
        }
    }

    /**
     * 刷新Token
     * 在Token即将过期时生成新的Token
     *
     * @param token 原Token
     * @return 新Token
     */
    @PostMapping("/refresh")
    public Result<String> refreshToken(@RequestParam("token") String token) {
        log.debug("Token刷新请求");
        
        try {
            String newToken = authService.refreshToken(token);
            if (newToken != null) {
                log.debug("Token刷新成功");
                return Result.success(newToken, "Token刷新成功");
            } else {
                log.warn("Token刷新失败");
                return Result.error("TOKEN_REFRESH_FAILED", "Token刷新失败");
            }
        } catch (Exception e) {
            log.error("Token刷新异常，错误：{}", e.getMessage(), e);
            return Result.error("TOKEN_REFRESH_ERROR", "Token刷新异常");
        }
    }

    /**
     * 获取当前用户信息
     * 基于Token获取当前登录用户的基本信息
     *
     * @return 当前用户信息
     */
    @GetMapping("/current")
    public Result<Long> getCurrentUser() {
        // 从Security上下文获取当前用户ID
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
        if (authentication != null && authentication.getPrincipal() instanceof Long userId) {
            log.debug("获取当前用户信息，用户ID：{}", userId);
            return Result.success(userId, "获取用户信息成功");
        } else {
            log.warn("获取当前用户信息失败，未找到认证信息");
            return Result.error("USER_NOT_LOGIN", "用户未登录");
        }
    }

    /**
     * 检查用户在线状态
     * 检查指定用户是否在线
     *
     * @param userId 用户ID
     * @return 在线状态
     */
    @GetMapping("/online/{userId}")
    public Result<Boolean> checkUserOnline(@PathVariable("userId") Long userId) {
        log.debug("检查用户在线状态，用户ID：{}", userId);
        
        try {
            boolean isOnline = authService.isUserOnline(userId);
            log.debug("用户在线状态，用户ID：{}，状态：{}", userId, isOnline);
            return Result.success(isOnline, "获取在线状态成功");
        } catch (Exception e) {
            log.error("检查用户在线状态异常，用户ID：{}，错误：{}", userId, e.getMessage(), e);
            return Result.error("CHECK_ONLINE_ERROR", "检查在线状态异常");
        }
    }
} 